package com.retail.bbq.cola.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;


@Slf4j
public class DateUtil {

    public static String dateToString(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssms");
        return dateFormat.format(date);
    }
    public static String dateToString2(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        return dateFormat.format(date);
    }

    public static String dateToStr(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return dateFormat.format(date);
    }

    public static String dateToStrWithTimeZone(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        return dateFormat.format(date);
    }
    public static String dateToDotStr(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
        return dateFormat.format(date);
    }
    public static String date2Str(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm");
        return dateFormat.format(date);
    }
    public static String dateToDotStrWithoutYear(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("MM.dd HH:mm:ss");
        return dateFormat.format(date);
    }
    public static String dateToDateStr(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return dateFormat.format(date);
    }
    public static Date dateAddMinute(Date operationTime, int minute) {
        Calendar now = Calendar.getInstance();
        if (operationTime == null) {
            return now.getTime();
        }
        now.setTime(operationTime);
        now.add(Calendar.MINUTE, minute);
        return now.getTime();
    }


    public static Date stringWithZoneToDate(String str) {
        if(StringUtils.isBlank(str)) {
            return null;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
        Date date = null;
        try {
            date = dateFormat.parse(str);
        } catch (Exception e) {
            log.info("DateUtil stringWithZoneToDate exception:dateStr={},exception={}", str, e);
        }
        return date;
    }
    public static Date stringToDate(String str) {
        if(StringUtils.isBlank(str)) {
            return null;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            date = dateFormat.parse(str);
        } catch (Exception e) {
            log.info("DateUtil stringToDate exception:dateStr={},exception={}", str, e);
        }
        return date;
    }

    public static Date getDateByMilliseconds(long milliseconds) {
        return new Date(milliseconds);
    }

    public static Date stringToDateZero(String str) {
        str += " 00:00:00";
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            date = dateFormat.parse(str);
        } catch (Exception e) {
            log.info("DateUtil stringToDate exception:dateStr={},exception={}", str, e);
        }
        return date;
    }

    public static Date localDateToDate(LocalDate localDate) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String format = fmt.format(localDate);
        format += " 00:00:00";
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        Date date = null;
        try {
            date = dateFormat.parse(format);
        } catch (Exception e) {
            log.info("DateUtil stringToDate exception:dateStr={},exception={}", format, e);
        }
        return date;
    }


    public static LocalDate dateToLocalDate(Date date) {

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String format = dateFormat.format(date);
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate parse = LocalDate.parse(format, fmt);
        return parse;
    }

    /**
     *  localDate zhuan
     * @param localDate 日期
     * @return 返回 yyyy-MM-dd 数据
     */
    public static String localDateToStr(LocalDate localDate) {
        return localDate.format(DateTimeFormatter.ISO_LOCAL_DATE);
    }
    public static String localDateToStr(LocalDateTime localDate) {
        return localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }
    /**
     * 输入日期字符串比如201703，返回当月第一天的Date
     */
    public static Date getMinDateMonth(String month) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
            Calendar calendar = Calendar.getInstance();
            Date nowDate = sdf.parse(month);
            calendar = Calendar.getInstance();
            calendar.setTime(nowDate);
            calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
            return calendar.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 输入日期字符串，返回当月最后一天的Date
     * @param month
     * @return
     */
    public static Date getMaxDateMonth(String month){
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
            Calendar calendar = Calendar.getInstance();
            Date nowDate=sdf.parse(month);
            calendar = Calendar.getInstance();
            calendar.setTime(nowDate);
            calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
            return calendar.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     *  根据传入时间 获取上周一时间
     * @param date
     * @return
     */
    public static Date getLastWeekMonday(Date date) {

        Calendar  cal = Calendar.getInstance();
        cal.setTime(date);
        //判断当前日期是否为周末，因为周末是本周第一天，如果不向后推迟一天的到的将是下周一的零点，而不是本周周一零点
        if (1 == cal.get(Calendar.DAY_OF_WEEK)) {
            cal.add(Calendar.DATE, -1);
        }
        //时间减去7天
        cal.add(Calendar.DAY_OF_MONTH, -7);
        //Calendar.MONDAY 这个是周一的意思      想获取周几就更换这个
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

        return cal.getTime();
    }
    public static String minusDays(LocalDate localDate,int gap) {
        return localDate.minusDays(gap).format(DateTimeFormatter.ISO_LOCAL_DATE);
    }
    public static String minusDays(LocalDateTime localDate, int gap) {
        return localDate.minusDays(gap).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
    }
    public static LocalDateTime minusDaysReturnTime(LocalDateTime localDate, int gap) {
        return localDate.minusDays(gap);
    }

    public static long minusDays(LocalDateTime localDate, int gap,String offsetId) {
        return localDate.minusDays(gap).toEpochSecond(ZoneOffset.of(offsetId));
    }


    public static void main(String[] args) throws ParseException {
//        System.out.println(minusDays(LocalDate.now(), 2));
//        Date date = new Date();
//        Calendar calendar = Calendar.getInstance();
//        calendar.setTime(date);
//        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
//        Date now = df.parse(" 2022-10-11 09:01");
//        Date start = df.parse(" 2022-10-10 09:10");
//        Date end = df.parse(" 2022-10-11 09:10");
//        System.out.println("isEffectiveDate :" + isEffectiveDate(now ,start ,end));
        Date date = stringWithZoneToDate("2015-05-20T13:29:35+08:00");
        System.out.println("date = " + date);
    }


    /**
     * 判断当前时间是否在[startTime, endTime]区间，注意三个参数的时间格式要一致
     * @param nowTime
     * @param startTime
     * @param endTime
     * @return 在时间段内返回true，不在返回false
     */
    public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return true;
        }

        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        return date.after(begin) && date.before(end);
    }

    /**
     * 比较时间差距是否在timeGap内
     * @param start
     * @param end
     * @param timeGap 单位：毫秒
     * @return
     */
    public static boolean timeGap(LocalDateTime start, LocalDateTime end, Long timeGap) {
        return Duration.between(start,end).toMillis() > timeGap;
    }
    public static long timeGap(Date start, Date end) {
        return start.getTime() - end.getTime();
    }

    public static LocalDateTime strToLocalDateTime(String dateStr) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return LocalDateTime.parse(dateStr,df);
    }

    public static String getMinutes(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("mm");
        return dateFormat.format(date);

    }
    public static LocalDate dayOfNextWeek(LocalDate localDate, DayOfWeek dayOfWeek) {
        return localDate.with(TemporalAdjusters.next(dayOfWeek));
    }
    public static LocalDate firstDayOfNextMonth(LocalDate localDate) {
        return localDate.with(TemporalAdjusters.firstDayOfNextMonth());
    }

    public static LocalDate firstDayOfMonth(LocalDate localDate) {
        return localDate.with(TemporalAdjusters.firstDayOfMonth());
    }
    public static LocalDate lastDayOfMonth(LocalDate localDate) {
        return localDate.with(TemporalAdjusters.lastDayOfMonth());
    }

    public static LocalDate strToLocalDate(String str) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return LocalDate.parse(str, fmt);
    }

    public static Date getEndDayOfYesterday() {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.add(Calendar.DAY_OF_MONTH, -1);
        return cal.getTime();
    }

    public static Date localDateTimeToDate(LocalDateTime localDateTime) {
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
        Instant instant2 = zonedDateTime.toInstant();
        return Date.from(instant2);
    }
}
